package com.demo2;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class VehicleProxyProvider {
    //设置一个将来要运行的对象，只要实现了vehicle接口的就行
    private Vehicle target_vehicle;

    public VehicleProxyProvider(Vehicle target_vehicle) {
        this.target_vehicle = target_vehicle;
    }

    //编写代码，返回一个Vehicle的代理对象
    public Vehicle getProxy(){
        //1.获取类加载对象
        ClassLoader loader = target_vehicle.getClass().getClassLoader();
        //2.获取接口类型数组，为什么是接口信息。而不是方法，是因为我们都是走接口的
        Class<?>[] interfaces = target_vehicle.getClass().getInterfaces();
        //3.创建InvocationHandler对象，以匿名内部类的方式来获取InvocationHandler对象
        //这个对象有一个方法是invoke，到时可以通过反射，动态调用目标对象的方法
        InvocationHandler invocationHandler = new InvocationHandler() {
            //invoke方法的参数

            //proxy:代理对象
            //method:目标对象的方法
            //args:方法的参数
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("开始执行了...");
                //4.通过反射来调用目标对象的方法
                Object result = method.invoke(target_vehicle, args);
                System.out.println("执行完毕了...");
                return result;
            }
        };
        //5.返回一个代理对象
        Vehicle proxy = (Vehicle) Proxy.newProxyInstance(loader, interfaces, invocationHandler);
        return proxy;
    }

    public static void main(String[] args) {
        //创建一个目标对象
        Vehicle vehicle = new Car();
        //创建一个代理对象
        VehicleProxyProvider proxyProvider = new VehicleProxyProvider(vehicle);
        Vehicle proxy = proxyProvider.getProxy();
        //调用方法
        proxy.run();
    }
}
